/*
 * bsp_nfc_lpcd.c
 *
 *  Created on: 2023年8月25日
 *      Author: fjx
 */
#include "bsp_nfc.h"
#include "bsp_nfc_fm17622_reg.h"
#include "bsp_nfc_lpcd.h"
#include "bsp_nfc_reader.h"
#include "app_log.h"
#include "app_gpio_i2c_fm17622.h"


#ifdef FM17622_DRIVER

/*
 * lpcd寄存器初始化配置
 *
 */
uint8_t lpcd_init_reg(void)
{
  /*
   * @step1 soft reset
   *
   */
  if(fm17622_soft_reset() == SUCCESS)
  {
      /* @note bit4 =1,晶振使用内部的1.5V建立,功耗低
       * @note bit2 LPCD_JUDGE_MODE  = 1,配置幅度检测模式使用的算法模式
       * @note bit1~bit0 LPCD过程中晶振使用的跨导， =0，功耗越低；==0x3,起振快，功耗低
       *
       */
      fm17622_set_reg_ext(0x24, 0x14);//请勿修改
      /* @note bit5~bit2  保留 0b11,10xx
       * @note bit1~bit0  10b 8个adc clk
       *
       */
      fm17622_set_reg_ext(0x25, 0x3A);//请勿修改
      /*
       * @step2、3
       * @note RF_DET_ENABLE bit5  =1,外部RF场功能使能
       * @note RF_DET_SEN  bit4~bit3 外部RF场灵敏度
       * @note RF_DET_SEN_00 RF场灵敏度 135mV,高灵敏度
       * @note RF_DET_SEN_01 RF场灵敏度 180mV,中灵敏度
       * @note RF_DET_SEN_10 RF场灵敏度 240mV,中灵敏度
       * @note RF_DET_SEN_11 RF场灵敏度 300mV,低灵敏度
       * @note LPCD_CTRL_MODE bit2~bit0 LPCD休眠阶段控制模式
       * @note                010b   LPCD休眠阶段内部低频始终控制
       */
      fm17622_set_reg_ext(JREG_LPCDCTRLMODE, (RF_DET_ENABLE|RF_DET_SEN_00|LPCD_ENABLE));//
      /*
       * @step4 TODO:为何该步骤注释和文档中提供的步骤不符合?
       *
       *
       */
      //      fm17622_set_reg_ext(JREG_LPCDDETECTMODE, LPCD_TXSCALE_4|LPCD_RX_CHANGE_MODE);
      /*
       * @step5
       * @note LPCD_SLEEPTIME bit5~bit0   休眠时长 0x00~0x3F
       *                      32ms*(LPCD_SLEEPTIME+1)
       *                      设置为544ms
       */
      fm17622_set_reg_ext(JREG_LPCDSLEEPTIMER, LPCD_SLEEPTIME);
      /* @step6、7、
       * @note LPCD_IRQINV  bit5  =1,IRQ引脚输出信号取反， 同COMMIEREG.IRQINV功能相同
       * @note LPCD_IRQPUSHPULL bit4 IRQ中断引脚配置
       *                        =1,CMOS输出；=0,开漏输出
       * @note LPCD_RF_TIMER bit3~bit0 幅度检测模式的发场时间  (200us+Ta)~(5us+Ta)   Ta=13us
       *
       */
      fm17622_set_reg_ext(JREG_LPCDRFTIMER, LPCD_IRQINV_ENABLE|LPCD_IRQ_PUSHPULL|LPCD_RFTIME_5us);//探测时间配置使用5us
      /*@note: step8
       *@note: LPCDTHRESH阈值设置,JREG_LPCDTHRESH_H(reset 24H),bit1~bit0 (00b);  TODO:缺省
       *@note:                 JREG_LPCDTHRESH_L(reset 10H),bit5~bit0.
       *
       */
      fm17622_set_reg_ext(JREG_LPCDTHRESH_L, LPCD_THRSH_L);
      /*@step9.1
       *@note: bit5~bit0  电导加权,TODO:操作距离
       */
      fm17622_set_reg_ext(JREG_LPCDTXCTRL2, LPCD_CWP);
      /*
       * @step9.2
       * @note bit3~bit0 电导值加权
       */
      fm17622_set_reg_ext(JREG_LPCDTXCTRL3, LPCD_CWN);
      /*@step10
       *@note 发送REQA之前的开场时间 bit4~bit0  (7ms~80us)
       */
      fm17622_set_reg_ext(JREG_LPCDREQATIMER,LPCD_REQA_TIME_5ms);//REQA操作时间,5ms兼容手机方案
      /*
       *@note LPCD_RXGAIN bit5~bit4       REQA检卡使用
       *@note LPCD_MINILEVEL bit3~bit2
       *@note LPCD_MODEWIDTH bit1
       *@note TODO:该字段在PDF流程上未使用??
       */
      fm17622_set_reg_ext(JREG_LPCDREQAANA,LPCD_RXGAIN_33DB | LPCD_MINLEVEL_9 | LPCD_MODWIDTH_38);

      /*
       * @step11
       * @note LPCD_TXPWR_SCALE bit5~bit3  命令检测场强为幅度检测场强的比例,默认值相等
       * @note LPCD_DETECT_MODE bit2~bit0  检测的工作模式
       *                        000b 幅度检测模式
       *                        001b 命令检测模式
       *                        010b 幅度命令组合模式
       *
       */
      fm17622_set_reg_ext(JREG_LPCDDETECTMODE,LPCD_TXSCALE_4|LPCD_COMBINE_MODE);//配置REQA检测功能
      return SUCCESS;
  }
  else
      return ERROR;
}
/*
 *@brief LPCD工作模式设置
 *@param mode=LPCD_MODE_ENABLE,开启;，mode=LPCD_MODE_DISABLE,关闭LPCD
 *
 */
void lpcd_set_mode(LPCD_MODE_EN mode)
{
  if(mode == LPCD_MODE_ENABLE){
      fm17622_hpd(0); //NPD = 0 进入LPCD模式
  }
  else{
      fm17622_hpd(1); //NPD = 1 退出LPCD模式
  }
}
/*
 *@brief 读取LPCD的ADC数据
 *
 */
void lpcd_get_adc_value(void)
{
  uint8_t reg,reg1;
  uint8_t lpcd_delta1,lpcd_delta2;
  {
    fm17622_get_reg_ext(JREG_LPCDDELTA_HI, &reg);
    fm17622_get_reg_ext(JREG_LPCDDELTA_LO, &reg1);
    lpcd_delta1 = (reg<<6) + reg1;
    lpcd_delta2 = ((reg<<6)>>8);

    DS_app_log_info("-> LPCD Delta:0x%2x-0x%2x\n",lpcd_delta2,lpcd_delta1);
  }
}
/*
 *@brief LPCD中断处理
 *
 */
void lpcd_irq_event (void)
{
  uint8_t reg;

  lpcd_set_mode(LPCD_MODE_DISABLE);     //NPD = 1,FM17622退出休眠模式

  DS_app_log_info("-> LPCD Detceted!\r\n");

  fm17622_get_reg_ext(JREG_LPCDIRQ, &reg);//读取LPCD中断标志
  fm17622_set_reg_ext(JREG_LPCDIRQ, reg);//CLEAR LPCD IRQ

  DS_app_log_info("IRQ =[0x%x] \n",reg);
  if(reg & 0x08){
      DS_app_log_info("-> LPCD IRQ RFDET SET!\r\n");
  }
  if(reg & 0x04){
      DS_app_log_info("-> LPCD IRQ RXCHANGE SET!\r\n");//LPCD中断标志
      lpcd_get_adc_value();//用于LPCD功能调试
  }
  if(reg & 0x02){
      DS_app_log_info("-> LPCD IRQ ATQAREC SET!\r\n");
  }

  if((reg & 0x08) ||(reg & 0x04)||(reg & 0x02)){
      lpcd_card_event();//卡片操作处理流程

  }

  lpcd_init_reg();//LPCD初始化
  lpcd_set_mode(LPCD_MODE_ENABLE);//返回LPCD模式
}

uint8_t lpcd_card_event(void)
{
  unsigned char result;

  fm17622_soft_reset();                     //读卡操作的寄存器复位
  fm17622_init_readerA();                   //TYPE A 初始化
  fm17622_setcw(TX1_TX2_CW_ENABLE);         //打开载波输出

  result = ReaderA_CardActivate();          //寻卡操作

  if(result == FM17622_SUCCESS)
  {
//TODO:需要增加读卡操作
      DS_app_log_hexdump_info("-> ATQA = ",PICC_A.ATQA,2);
      DS_app_log_hexdump_info("-> UID = ",PICC_A.UID, 4);
      DS_app_log_info("-> SAK = 0x%02x\n",PICC_A.SAK);
    //此处添加用户卡片操作函数
    //MIFARE_EVENT();
    //用户卡片操作函数结束

//    mDelay(100);  //TODO: 延时

  }
  else{
      DS_app_log_info("-> CardActivate Fail!\r\n");

  }
  fm17622_setcw(TX1_TX2_CW_DISABLE);                                         //关闭载波输出
  return result;
}

#endif //end of "FM17622_DRIVER"
